/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package l2s.commons.db;

import com.jolbox.bonecp.BoneCP;
import com.jolbox.bonecp.BoneCPConfig;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import l2s.commons.type.ServerType;

public class DatabaseFactory
{
	private static final Logger _log = LoggerFactory.getLogger(DatabaseFactory.class.getName());
	
	private static BoneCP connectionPool;
	
	public static void init()
	{
		_log.info("DatabaseFactory: Initializing...");
		
		final File configFile = new File("./config/database.xml");
		
		try (FileInputStream fis = new FileInputStream(configFile);
			InputStream bis = new BufferedInputStream(fis))
		{
			final BoneCPConfig config = new BoneCPConfig(bis, ServerType.getServerTypeName());
			
			_log.info("DatabaseFactory: jdbc url '{}'.", config.getJdbcUrl());
			_log.info("DatabaseFactory: user name '{}'.", config.getUsername());
			_log.info("DatabaseFactory: password '{}'.", config.getPassword());
			
			connectionPool = new BoneCP(config);
			
			// Test the connection
			connectionPool.getConnection().close();
		}
		catch (Exception e)
		{
			throw new Error("DatabaseFactory: Failed to init database connections: " + e.getMessage(), e);
		}
	}
	
	/**
	 * Safety string.
	 * @param whatToCheck the what to check
	 * @return the string
	 */
	public static final String safetyString(String... whatToCheck)
	{
		char brace = '`';
		int length = 0;
		
		for (String word : whatToCheck)
		{
			length += word.length() + 4;
		}
		
		final StringBuilder sbResult = new StringBuilder(length);
		
		for (String word : whatToCheck)
		{
			if (sbResult.length() > 0)
			{
				sbResult.append(", ");
			}
			
			sbResult.append(brace);
			sbResult.append(word);
			sbResult.append(brace);
		}
		
		return sbResult.toString();
	}
	
	public static Connection getConnection()
	{
		Connection con = null;
		
		while (con == null)
		{
			try
			{
				con = connectionPool.getConnection();
			}
			catch (SQLException e)
			{
				_log.warn("DatabaseFactory: getConnection() failed, trying again " + e.getMessage());
			}
		}
		return con;
	}
	
	public static void shutdown()
	{
		connectionPool.shutdown();
	}
}